home *** CD-ROM | disk | FTP | other *** search
- /*
- * Retabulates files to different tab stops
- *
- * Options:
- * -f = Inhibit filling with spaces
- * -s = Convert spaces to tabs where possible
- * i=n,... = Specify input tab stops
- * o=n,... = Specify output tab stops
- *
- * Notes:
- * RETAB processes multiple files, and allows the tab settings to be defined
- * for each file. The '-f -s i= and o=' parameters must be specified BEFORE
- * the file name where they are to have effect.
- *
- * If more tabs are present in the input or output file than were specified
- * (using I= and O=), RETAB assumes that the tabs continue at the spacing of
- * the last two stops. Therefore, if the tabs are at regular intervals, only
- * the first tab stop need be given.
- *
- * Both input and output tabs default to 8 space intervals.
- *
- * If 'O=0' is specified, RETAB will convert all tabs in the input file to
- * the appriopriate number of spaces.
- *
- * Examples:
- * retab i=4 tab4.fil >tab8.fil
- * retab o=4 tab8.fil >tab4.fil
- * retab i=4 o=2 tab4.file i=8 tab8.fil >tab2.fil
- * retab o=0 tab8.file >space.fil
- *
- * Copyright 1988-1994 Dave Dunfied
- * All rights reserved.
- *
- * Permission granted for personal (non-commercial) use only.
- *
- * Compile command: cc retab -fop
- */
- #include <stdio.h>
-
- #define TAB_STOPS 25 /* maximum number of tab stops supported */
-
- unsigned itabs[TAB_STOPS], otabs[TAB_STOPS];
-
- char fill = -1, space = 0, *ptr;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- unsigned i, j, k, l;
- FILE *fp;
- char flag, flag1;
-
- flag = -1;
- flag1 = 0;
-
- /* Install default tabs at 8 space intervals */
- for(i=j=0; i < TAB_STOPS; ++i)
- itabs[i] = otabs[i] = (j += 8);
-
- /* parse the options and parameters */
- for(i=1; i < argc; ++i) {
- ptr = argv[i];
- switch((tolower(*ptr++) << 8) | tolower(*ptr++)) {
- case '-f': /* disable fill */
- fill = 0;
- goto parm;
- case '-s': /* enable space processing */
- space = -1;
- goto parm;
- case '-i': /* specify input tabs */
- j = 0;
- do
- itabs[j++] = k = l = get_dec();
- while(*ptr++ == ',');
- if(j > 1)
- k -= itabs[j-2];
- while(j < (sizeof(itabs)/2))
- itabs[j++] = l += k;
- goto parm;
- case 'o=': /* specify output tabs */
- j = 0;
- do
- otabs[j++] = k = l = get_dec();
- while(*ptr++ == ',');
- if(j > 1)
- k -= otabs[j-2];
- while(j < (sizeof(otabs)/2))
- otabs[j++] = l += k;
- parm:
- flag1 = -1;
- break;
- default:
- flag = flag1 = 0;
- if(fp = fopen(argv[i], "r")) {
- do_convert(fp);
- fclose(fp); }
- else {
- fputs("RETAB: Cannot open: '", stderr);
- fputs(argv[i], stderr);
- fputs("'\n", stderr); } } }
-
- if(flag1)
- fputs("RETAB: Trailing options have no effect!!!\n", stderr);
-
- if(flag)
- fputs("\nUse: retab [-f -s i=n,n,n... o=n,n,n] <file*> >output_file\n\nCopyright 1988-1994 Dave Dunfield\nAll rights reserved.\n", stderr);
- }
-
- /* get a decimal number from the input line */
- get_dec()
- {
- unsigned value;
-
- value = 0;
- if(isdigit(*ptr)) { /* decimal number */
- while(isdigit(*ptr))
- value = (value * 10) + *ptr++ - '0'; }
- else {
- fputs("RETAB: Invalid number\n", stderr);
- exit(-1); }
-
- return(value);
- }
-
- /* do the tab conversion */
- do_convert(fp)
- FILE *fp;
- {
- unsigned ip, op, i, scount;
- char chr;
-
- ip = op = scount = 0;
-
- while((chr = getc(fp)) != -1) { /* read entire file */
- if(chr == 0x09) { /* found a tab */
- ip += scount; /* offset for any spaces */
- for(i=0; ip >= itabs[i]; ++i); /* next input tab position */
- ip = itabs[i];
- scount = 0; }
- else if((chr == ' ') && space) /* convert spaces */
- ++scount;
- else { /* std character */
- /*
- * if more than 1 space is encountered, or a single space
- * is adjacent to a one or more tabs, convert it to tabs.
- */
- if((op < ip) || (scount > 1)) {
- ip += scount;
- scount = 0; }
- /*
- * if the output pointer lags behind the input pointer
- * we have received tabs or multiple spaces. Generate
- * tabs in the output file to restore the position.
- */
- if(op < ip) { /* we have whitespace to fill in */
- for(i=0; op >= otabs[i]; ++i); /* next output tab position */
- while(otabs[i] <= ip) {
- putc(0x09, stdout);
- op = otabs[i++]; }
- /*
- * Input pointer is not on an output tab stop, fill with
- * spaces as nessary, to restore the correct position.
- */
- if(fill) while(op < ip) {
- putc(' ', stdout);
- ++op; }
- else
- op = ip; }
- ++ip;
- /*
- * Single space received, copy to output file
- */
- if(scount) {
- putc(' ', stdout);
- ++op;
- ++ip;
- scount = 0; }
- /*
- * Copy character into output file
- */
- putc(chr, stdout);
- ++op;
- if(chr == '\n')
- ip = op = 0; } }
- }
-